home *** CD-ROM | disk | FTP | other *** search
/ Revista CD Expert 8 / Revista CD Expert nº 08 CD1.iso / Utilitarios / Programacao / Pacific C for DOS / EXAMPLES / TALK.C < prev    next >
C/C++ Source or Header  |  1995-03-08  |  5KB  |  284 lines

  1. /*
  2.  *    Simple talk program which will talk to whatever is on the end
  3.  *    of a standard PC serial port.
  4.  *
  5.  *    Usage:
  6.  *        talk [-s19200] [comN]
  7.  *
  8.  *    Defaults:    19200 baud, COM1
  9.  *
  10.  *    Example, to talk to COM2 at 4800 baud:
  11.  *
  12.  *    talk -s4800 com2
  13.  *
  14.  *    To compile:
  15.  *
  16.  *    c -O -Zg talk.c
  17.  *
  18.  */
  19.  
  20. #include    <ctype.h>
  21. #include    <conio.h>
  22. #include    <stdio.h>
  23. #include    <string.h>
  24. #include    <stdlib.h>
  25. #include    <signal.h>
  26. #include    <ioctl.h>
  27. #include    <intrpt.h>
  28.  
  29. #define BOOL    unsigned char
  30. #define FALSE    (BOOL)0
  31. #define TRUE    (BOOL)1
  32.  
  33. #define MENU        0x1C
  34. #define CONTINUE    0
  35. #define FINISH        1
  36.  
  37. static BOOL    debug = FALSE;
  38. static BOOL    printable[32] = {0,0,0,0,0,0,0,1,1,1,1,0,0,1,0,0,
  39.                  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  40.  
  41. /*    Routines to access an IBM serial port    */
  42.  
  43. #define    PORT1    ((port unsigned char *)0x3F8)    /* COM1 */
  44. #define    PORT2    ((port unsigned char *)0x2F8)    /* COM2 */
  45.  
  46. #define    IRQ4    (far isr *)0x30        /* for COM1 */
  47. #define    IRQ3    (far isr *)0x2C        /* for COM2 */
  48.  
  49. #define    MSK4    0x10
  50. #define    MSK3    0x08
  51.  
  52. #define    ICR    ((port unsigned char *)0x20)    /* interrupt control register */
  53. #define    IMR    ((port unsigned char *)0x21)    /* interrupt mask register */
  54. #define    EOI    0x20                /* end of interrupt command */
  55.  
  56. static port unsigned char *    PORT;
  57.  
  58. static struct
  59. {
  60.     unsigned    rate;
  61.     unsigned char    bits;
  62. }    baurates[] =
  63. {
  64.     38400, 3,
  65.     19200, 6,
  66.     9600, 12,
  67.     4800, 24,
  68.     2400, 48,
  69.     1200, 96
  70. };
  71.  
  72. static char        inbuf[256];
  73. static unsigned char    iptr, optr, tmp;
  74. static BOOL        kchar;
  75.  
  76. /*
  77.  *    Prototypes for all functions in talk.c
  78.  */
  79.  
  80. static unsigned char    gbyte(unsigned char);
  81. static unsigned char    menu(void);
  82. static void        cflush(void);
  83. static void        cominit(char *, unsigned short);
  84. static void interrupt    service(void);
  85. static void        sbyte(unsigned char);
  86. static void        sendfile(void);
  87. static void        sinkline(void);
  88. static void        terminal(void);
  89.  
  90. static void interrupt
  91. service(void)
  92. {
  93.     inbuf[iptr] = *PORT;
  94.     tmp = iptr+1;
  95.     if(tmp != optr)
  96.         iptr = tmp;
  97.     *ICR = EOI;
  98. }
  99.  
  100. void
  101. disint(void)
  102. {
  103.     PORT[1] = 0;
  104.     *IMR = *IMR | (PORT == PORT1 ? MSK4 : MSK3);
  105. }
  106.  
  107. static void
  108. cominit(comname, baud)
  109. register char *    comname;
  110. unsigned short    baud;
  111. {
  112.     register unsigned char    i;
  113.  
  114.     if(strcmp(comname, "com2") == 0 || strcmp(comname, "COM2") == 0)
  115.         PORT = PORT2;
  116.     else
  117.         PORT = PORT1;
  118.     for(i = 0 ; baurates[i].rate != baud ; i++)
  119.         if(i == sizeof baurates/sizeof baurates[0]) {
  120.             i = 1;    /* default 19200 */
  121.             break;
  122.         }
  123.     set_vector(PORT == PORT1 ? IRQ4 : IRQ3, service);
  124.     PORT[3] = 0x80;    /* enable divisor latches */
  125.     PORT[0] = baurates[i].bits;
  126.     PORT[1] = baurates[i].bits >> 8;
  127.     PORT[3] = 3;    /* 8 bits, 1 stop, no parity */
  128.     PORT[4] = 0xB;    /* set DTR and RTS , enable interrupts */
  129.     i = *PORT;        /* clear rx buffer */
  130.     PORT[1] = 1;    /* enable receive interrupts */
  131.     *IMR = *IMR & ~(PORT == PORT1 ? MSK4 : MSK3);
  132.     atexit(disint);
  133. }
  134.  
  135. static void
  136. sbyte(c)
  137. unsigned char    c;
  138. {
  139.     PORT[1] = 1;
  140.     *IMR = *IMR & ~(PORT == PORT1 ? MSK4 : MSK3);
  141.     while((PORT[5] & 0x20) == 0)
  142.         continue;
  143.     *PORT = c;
  144. }
  145.  
  146. static unsigned char
  147. gbyte(waitchar)
  148. BOOL    waitchar;
  149. {
  150.     register unsigned char    c;
  151.  
  152.     kchar = FALSE;
  153.     PORT[1] = 1;
  154.     *IMR = *IMR & ~(PORT == PORT1 ? MSK4 : MSK3);
  155.     if (waitchar)
  156.         while(iptr == optr)
  157.             if(kbhit()) {
  158.                 kchar = TRUE;
  159.                 return getch();
  160.             }
  161.     if (iptr != optr) {
  162.         di();
  163.         c = inbuf[optr++];
  164.         ei();
  165.         return c;
  166.     } else
  167.         return 0;
  168. }
  169.  
  170. static void
  171. cflush()
  172. {
  173.     iptr = optr;
  174. }
  175.  
  176. static void
  177. sinkline()
  178. {
  179.     while ((gbyte(TRUE) != 13) && !kchar) ;
  180. }
  181.  
  182. static void
  183. sendfile()
  184. {
  185.     register FILE    *hexfile;
  186.     register char    *bufptr;
  187.     char        buf[256];
  188.     unsigned char    abort;
  189.  
  190.     printf("\nEnter pathname:");
  191.     gets(buf);
  192.     if (hexfile = fopen(buf, "r")) {
  193.         printf("Sending file...\n");
  194.         abort = 0;
  195.         while (fgets(buf, sizeof buf, hexfile)) {
  196.             for (bufptr = buf; *bufptr && !abort; bufptr++) {
  197.                 if (*bufptr >= 32 || *bufptr == 13)
  198.                     sbyte(*bufptr);
  199.                 abort = gbyte(FALSE);
  200.             }
  201.             if (abort)
  202.                 break;
  203.         }
  204.         if (abort)
  205.             sinkline();
  206.         printf("Finished\n");
  207.         fclose(hexfile);
  208.     } else
  209.         printf("File not found\n");
  210. }
  211.  
  212. static unsigned char
  213. menu()
  214. {
  215.     char    option;
  216.  
  217.     printf("\nTALK MENU\nD - turn debug display %s\nS - send a file\nX - exit to DOS\n\nAny other key re-connects\n\nEnter option - ", debug ? "OFF" : "ON");
  218.     fflush(stdout);
  219.     putch(option = toupper(getch()));
  220.     switch(option) {
  221.         case 'D':
  222.             debug = !debug;
  223.             break;
  224.         case 'S':
  225.             sendfile();
  226.             break;
  227.         case 'X':
  228.             return FINISH;
  229.     }
  230.     putch('\n');
  231.     return CONTINUE;
  232. }
  233.  
  234. static void
  235. terminal()
  236. {
  237.     unsigned char    c;
  238.  
  239.     signal(SIGINT, SIG_IGN);
  240.     for(;;) {
  241.         c = gbyte(TRUE);
  242.         if (kchar) {
  243.             if (c != MENU)
  244.                 sbyte(c);
  245.             else if (menu() == FINISH)
  246.                 return;
  247.         } else {
  248.             if (c < 32) {
  249.                 if (debug) {
  250.                     printf("[%02X]", c);
  251.                     fflush(stdout);
  252.                 } else if (printable[c])
  253.                     putch(c);
  254.             } else
  255.                 putch(c);
  256.         }
  257.     }
  258. }
  259.  
  260. main(argc, argv)
  261. int    argc;
  262. char    **argv;
  263. {
  264.     char    *comname = "COM1";
  265.     char    *speed = "19200";
  266.  
  267.     setvbuf(stdout, 0, _IOLBF, 0);
  268.     if (argc > 1) {
  269.         if (argv[1][0] == '-' && tolower(argv[1][1]) == 's') {
  270.             speed = argv[1] + 2;
  271.             ++argv;
  272.             --argc;
  273.         }
  274.         comname = argv[1];
  275.     }
  276.     cominit(comname, atoi(speed));
  277.     cflush();
  278.     printf("TALK VERSION 1.00\nEnter control-\\ for TALK menu\n");
  279.     terminal();
  280.     disint();
  281.     printf("\nFinished\n");
  282.     exit(0);
  283. }
  284.